

#include <sudoku.h>

sudoku *sdk;

int main(int argc, char **argv){

  printf("Sudosolve test program: version %s\n", _SDK_VERSION);
  printf("  Data sizes:\n");
  printf("    int:      %d\n", sizeof(int));
  printf("    long int: %d\n", sizeof(long int));
  printf("    void *:   %d\n", sizeof(void *));
  printf("  Struct sizes:\n");
  printf("    struct _sdk_square:    %d\n", sizeof(struct _sdk_square));
  printf("    struct _sdk_sudoku:    %d\n", sizeof(struct _sdk_sudoku));
  printf("    struct _sdk_sub_mtx:   %d\n", sizeof(struct _sdk_sub_mtx));
  printf("    struct _sdk_rc:        %d\n", sizeof(struct _sdk_rc));
  
#ifdef _DEBUG
  printf(" ** Compliled with debug on. **\n");
#endif
  if (argv[1] == NULL){
    printf("No sudoku file passed\n");
    printf("Usage: sdk_test <sudoku_file_path>\n");
    _sdk_die_msg("Exiting", 1);
  }
  printf("Loading sudoku from this file: %s\n", argv[1]);

  sdk = sdk_load_sudoku(argv[1]);
  _sdk_print_sdk_vals(sdk);

  //fprintf(stderr, "Testing hidden singles algo:\n");
  //sdk_sub_mtx_overlay *overlay = SDK_SUB_MTX_OVERLAY_ALLOC();
  //sdk_sub_mtx *box = SDK_SUB_MTX_ALLOC();

  /*
  sdk_sub_mtx box;
  sdk_sub_mtx_overlay overlay;
  memset(&box, 0, sizeof(box));
  memset(&overlay, 0, sizeof(overlay));

  fprintf(stderr, "Building test box:\n");
  int i, j;
  
  for ( i = 0; i < SDK_SUB_MTX_SIZE; i++){
    for ( j = 0; j < SDK_SUB_MTX_SIZE; j++){
      sdk_list_add_num(&(box.sdk_data[i][j].pos), (i * 3) + j + 1);
    }
  }

  box.sdk_data[0][0].value = 2;
  box.sdk_data[0][2].value = 1;
  box.sdk_data[1][1].value = 9;
  box.sdk_data[2][2].value = 8;

  sdk_list_add_num(&box.sdk_data[0][0].pos, 2);
  sdk_list_add_num(&box.sdk_data[0][2].pos, 1);
  sdk_list_add_num(&box.sdk_data[1][1].pos, 9);
  sdk_list_add_num(&box.sdk_data[2][2].pos, 8);

  // 5 and 7 are the two hidden singles here
  sdk_list_add_num(&box.sdk_data[0][1].pos, 3);
  sdk_list_add_num(&box.sdk_data[0][1].pos, 7);
  sdk_list_add_num(&box.sdk_data[1][0].pos, 3);
  sdk_list_add_num(&box.sdk_data[1][0].pos, 4);
  sdk_list_add_num(&box.sdk_data[1][2].pos, 3);
  sdk_list_add_num(&box.sdk_data[1][2].pos, 4);
  sdk_list_add_num(&box.sdk_data[1][2].pos, 5);
  sdk_list_add_num(&box.sdk_data[2][0].pos, 4);
  sdk_list_add_num(&box.sdk_data[2][0].pos, 3);
  sdk_list_add_num(&box.sdk_data[2][1].pos, 3);
  sdk_list_add_num(&box.sdk_data[2][1].pos, 6);
  
  _sdk_print_sub_mtx_lists(&box);

  fprintf(stderr, "Values of box:\n");
  _sdk_print_sub_mtx(&box);

  fprintf(stderr, "Generating overlay square:\n");
  for ( i = 0; i < SDK_SUB_MTX_SIZE; i++){
    for ( j = 0; j < SDK_SUB_MTX_SIZE; j++){
      overlay.sdk_data[i][j] = &SDK_ELEM((&box), i, j);
    }
  }
  _sdk_print_mtx_overlay(&overlay);

  fprintf(stderr, "Running hidden single finding function:\n");
  _sdk_hidden_singles_in_sub_mtx(&overlay);
  _sdk_print_sub_mtx(&box);
  */
  /*
  fprintf(stderr, "Testing the hidden singles solving function:\n");
  int solved = _sdk_solve_hidden_singles(sdk);

  fprintf(stderr, "Solved squares: %d\n", solved);
  _sdk_print_sdk_vals(sdk);
  */
  fprintf(stderr, "Testing the solve function:\n");
  sdk_solve(sdk);
  _sdk_print_sdk_vals(sdk);

  fprintf(stderr, "Checking for solvablity: ");
  if (sdk_solvable(sdk)){
    fprintf(stderr, "yes.\n");
  } else {
    fprintf(stderr, "no.\n");
  }
  
  fprintf(stderr, "Running the recursive solving algorithm:\n");
  sudoku *solved = _sdk_rec_solve(sdk);
  _sdk_print_sdk_vals(solved);
  
  fprintf(stderr, "Reloading sudoku...\n");
  sdk_free_sudoku(sdk);
  sdk = sdk_load_sudoku(argv[1]);
  fprintf(stderr, "Solving 10000 sudokus:\n");
  int i;
  for ( i = 0; i < 10000; i++){
    if ( i % 1000 == 0){
      fprintf(stderr, "solved: %d\n", i);
      fprintf(stderr, "  Total Memory leaked: %ld\n", _sdk_memory);
    }
    sudoku *tmp = _sdk_rec_solve(sdk);
    sdk_free_sudoku(tmp);
  }
  
  fprintf(stderr, "Total Memory leaked: %ld\n", _sdk_memory);

}
